﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System.Net;

namespace Sky.App.AI
{
    public class DeepSeek
    {
        public static async Task<List<MessageItem>> SendAsync(string questions, List<MessageItem> items)
        {
            string jsonString = await GetJsonStringAsync(questions, items);
            var client = new RestClient(Config.DeepSeekAppUrl());
            var request = new RestRequest("", Method.Post);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("Authorization", $"Bearer {Config.DeepSeekAppKey()}");
            request.AddJsonBody(jsonString);
            var response = await client.ExecuteAsync(request);
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var result = JsonConvert.DeserializeObject<ResponseData>(response.Content);
                if (result is not null)
                {
                    var choices = result.Choices;
                    var messages = choices.Select(s => s.Message).ToList();
                    var message = messages.First();
                    if (message is not null)
                    {
                        string answers = message.Content;
                        var item = new MessageItem()
                        {
                            ID = Guid.NewGuid().ToString(),
                            Questions = questions,
                            Answers = answers,
                            HtmlAnswers = answers,
                            CreateTime = DateTime.Now,
                        };
                        items.Add(item);
                        return await Task.FromResult(items);
                    }
                }
            }
            return await Task.FromResult(items);
        }

        protected static async Task<string> GetJsonStringAsync(string questions, List<MessageItem> items)
        {
            var obj = new JObject
            {
                ["model"] = "deepseek-chat",
                ["frequency_penalty"] = 0,
                ["max_Tokens"] = 2048,
                ["presence_penalty"] = 0,
                ["stop"] = null,
                ["stream"] = false,
                ["stream_options"] = null,
                ["temperature"] = 1,
                ["top_p"] = 1,
                ["tools"] = null,
                ["tool_choice"] = "none",
                ["logprobs"] = false,
                ["top_logprobs"] = null,
                ["response_format"] = new JObject { ["type"] = "text" }
            };

            var arr = new JArray();
            if (items.Count == 0)
            {
                var message = new JObject()
                {
                    ["content"] = "一个乐于助人的助手",
                    ["role"] = "system"
                };
                arr.Add(message);
            }

            var list = await GetMultipleListAsync(questions, items);
            foreach (var model in list)
            {
                var message = new JObject()
                {
                    ["content"] = model.Content,
                    ["role"] = "user"
                };
                arr.Add(message);
            }
            obj["messages"] = arr;
            return await Task.FromResult(obj.ToString());
        }

        protected static async Task<List<Message>> GetMultipleListAsync(string questions, List<MessageItem> list)
        {
            if (list.Count > 5)
                list = list.Take(5).ToList();
            var items = new List<Message>();
            var item = new Message();
            foreach (var model in list)
            {
                item = new Message()
                {
                    Role = "user",
                    Content = model.Questions,
                };
                items.Add(item);
                item = new Message()
                {
                    Role = "assistant",
                    Content = model.Answers,
                };
                items.Add(item);
            }
            item = new Message()
            {
                Role = "user",
                Content = questions,
            };
            items.Add(item);
            return await Task.FromResult(items);
        }

        public class ResponseData
        {
            public string ID { get; set; } = "";
            public string Object { get; set; } = "";
            public int Created { get; set; } = 0;
            public string Model { get; set; } = "";
            public List<Choice> Choices { get; set; } = [];
            public Usage Usage { get; set; } = new();
            public string System_Fingerprint { get; set; } = "";
        }

        public class Usage
        {
            public int Prompt_Tokens { get; set; } = 0;
            public int Completion_Tokens { get; set; } = 0;
            public int Total_Tokens { get; set; } = 0;
            public int Prompt_Cache_Hit_Tokens { get; set; } = 0;
            public int Prompt_Cache_Miss_Tokens { get; set; } = 0;
        }

        public class Choice
        {
            public int Index { get; set; } = 0;
            public Message Message { get; set; } = new();
            public object Logprobs { get; set; } = new();
            public string Finish_Reason { get; set; } = "";
        }

        public class Message
        {
            public string Role { get; set; } = "";
            public string Content { get; set; } = "";
        }

        public class MessageItem
        {
            public string ID { get; set; } = string.Empty;
            public string Questions { get; set; } = string.Empty;
            public string Answers { get; set; } = string.Empty;
            public string HtmlAnswers { get; set; } = string.Empty;
            public DateTime CreateTime { get; set; }
        }
    }
}